﻿using System.Windows;
using Bookvar.ObjectModel;
using Bookvar.ObjectModel.Actions;

namespace Bookvar.UI.DragDrop.Actions
{
    public abstract class TopicDropActionBase : DropActionBase
    {
        private IDataObject data;

        protected IDataObject Data
        {
            get { return data; }
        }

        public override void Execute( DragEventArgs args, MindMapPanel panel, Point dropPoint )
        {
            data = args.Data;
            var compositeAction = new CompositeAction();

            TopicContentPresenter presenter;
            //the topic on which the mouse button is released
            TopicContentPresenter targetPresenter = GetTargetPresenter( data, panel, dropPoint );

            if ( data.GetDataPresent( BookvarDataFormats.Topic.Name ) )
            {
                presenter = data.GetData( BookvarDataFormats.Topic.Name ) as TopicContentPresenter;
            }
            //create new topic
            else
            {
                //if no target topic or copying - create new topic
                if ( targetPresenter == null || ( args.Effects & DragDropEffects.Copy ) == DragDropEffects.Copy )
                {
                    var topic = new Topic();

                    var addSubTopicAction = new AddTopicAction( topic ) { Parent = panel.MainTopic };
                    addSubTopicAction.Execute();
                    compositeAction.AddExecuted( addSubTopicAction );

                    var changeTopicPositionAction =
                        new ChangeTopicPositionByOffsetAction( topic, dropPoint, panel.Mindmap );
                    changeTopicPositionAction.Execute();
                    compositeAction.AddExecuted( changeTopicPositionAction );
                    
                    presenter = panel.FindTopicContentPresenter(topic.ID);
                    
//                    panel.MainTopic.SubTopics.Add( topic );
//
//                    presenter = panel.FindTopicContentPresenter( topic.ID );
//                    presenter.X = dropPoint.X;
//                    presenter.Y = dropPoint.Y;
//                    presenter.IsMoved = true;
                }
                else
                {
                    presenter = targetPresenter;
                }
            }

            if ( presenter != null )
            {
                if ( targetPresenter != null && targetPresenter != presenter )
                {
                    //topic is dragged over some of its children => do nothing
                    if ( presenter.Topic.FindTopic( targetPresenter.Topic.ID ) != null )
                    {
                        return;
                    }

                    var changeParentAction = TopicActions.CreateChangeTopicParentAction(
                        presenter.Topic, targetPresenter.Topic, panel.Mindmap);

                    compositeAction.Add( changeParentAction );
                    ActionService.Execute( compositeAction );
                }
                else
                {
                    // If no action was created pass a DoNotingAction
                    Execute( compositeAction, presenter, dropPoint );
                }
                presenter.Owner.InvalidateTopics();
            }
        }

        protected static TopicContentPresenter GetTargetPresenter( IDataObject dataObject, MindMapPanel panel,
                                                                   Point dropPoint )
        {
            Point actualPosition = dropPoint;
            //offset should be added
            if ( dataObject.GetDataPresent( BookvarDataFormats.OffsetPoint.Name ) )
            {
                Point offset = (Point) dataObject.GetData( BookvarDataFormats.OffsetPoint.Name );
                actualPosition.X += offset.X;
                actualPosition.Y += offset.Y;
            }
            return panel.GetTopicPresenterByPosition( actualPosition );
        }

        public abstract void Execute( CompositeAction compositeAction, TopicContentPresenter presenter, Point dropPoint );
    }
}